package org.xiaohanghu.starter;

/**
 * @author xiaohanghu
 */
public class Logger {

	public static final int LEVEL_DEBUG = 1;
	public static final int LEVEL_INFO = 2;
	public static final int LEVEL_WARN = 3;
	public static final int LEVEL_ERROR = 4;

	public static final String LEVEL_DEBUG_NAME = "DEBUG";
	public static final String LEVEL_INFO_NAME = "INFO";
	public static final String LEVEL_WARN_NAME = "WARN";
	public static final String LEVEL_ERROR_NAME = "ERROR";

	public static int getLevel(String level) {
		level = level.trim();
		level = level.toUpperCase();
		if (LEVEL_DEBUG_NAME.equals(level)) {
			return LEVEL_DEBUG;
		} else if (LEVEL_INFO_NAME.equals(level)) {
			return LEVEL_INFO;
		} else if (LEVEL_WARN_NAME.equals(level)) {
			return LEVEL_WARN;
		} else if (LEVEL_ERROR_NAME.equals(level)) {
			return LEVEL_ERROR;
		}
		throw new IllegalStateException("Unsupported log level [" + level + "]");
	}

	private int lever;

	public Logger(int lever) {
		this.lever = lever;
	}

	public void setLever(int lever) {
		this.lever = lever;
	}

	protected String creatMessage(int lever, Object message) {
		StringBuilder stringBuilder = new StringBuilder();
		appendMessage(lever, message, stringBuilder);
		return stringBuilder.toString();
	}

	protected String creatMessage(int lever, Object message, Throwable t) {
		StringBuilder stringBuilder = new StringBuilder();
		appendMessage(lever, message, stringBuilder);
		stringBuilder.append("\r\n");
		stringBuilder.append(t.getStackTrace());
		return stringBuilder.toString();
	}

	protected void appendMessage(int lever, Object message,
			StringBuilder stringBuilder) {
		String tag = null;
		switch (lever) {
		case LEVEL_DEBUG:
			tag = "[DEBUG]";
			break;
		case LEVEL_INFO:
			tag = "[INFO ]";
			break;
		case LEVEL_WARN:
			tag = "[WARN ]";
			break;
		case LEVEL_ERROR:
			tag = "[ERROR]";
			break;
		}
		stringBuilder.append(tag);
		stringBuilder.append(" ");
		stringBuilder.append(message);
	}

	/**
	 * <p>
	 * Log a message with debug log level.
	 * </p>
	 * 
	 * @param message
	 *            log this message
	 */
	public void debug(Object message) {
		if (lever <= LEVEL_DEBUG) {
			String msg = creatMessage(LEVEL_DEBUG, message);
			System.out.println(msg);
		}
	}

	/**
	 * <p>
	 * Log a message with info log level.
	 * </p>
	 * 
	 * @param message
	 *            log this message
	 */
	public void info(Object message) {
		if (lever <= LEVEL_INFO) {
			String msg = creatMessage(LEVEL_INFO, message);
			System.out.println(msg);
		}
	}

	/**
	 * <p>
	 * Log a message with warn log level.
	 * </p>
	 * 
	 * @param message
	 *            log this message
	 */
	public void warn(Object message) {
		if (lever <= LEVEL_WARN) {
			String msg = creatMessage(LEVEL_WARN, message);
			System.out.println(msg);
		}
	}

	/**
	 * <p>
	 * Log a message with error log level.
	 * </p>
	 * 
	 * @param message
	 *            log this message
	 */
	public void error(Object message) {
		if (lever <= LEVEL_ERROR) {
			String msg = creatMessage(LEVEL_ERROR, message);
			System.err.println(msg);
		}
	}

	/**
	 * <p>
	 * Log an error with error log level.
	 * </p>
	 * 
	 * @param message
	 *            log this message
	 * @param t
	 *            log this cause
	 */
	public void error(Object message, Throwable t) {
		if (lever <= LEVEL_ERROR) {
			String msg = creatMessage(LEVEL_ERROR, message);
			System.err.println(msg);
			t.printStackTrace(System.err);
		}
	}

	private static volatile Logger logger = null;

	public static Logger getLogger() {
		if (null != logger) {
			return logger;
		}
		synchronized (Logger.class) {
			if (null == logger) {
				logger = new Logger(Logger.LEVEL_ERROR);
			}
		}
		return logger;
	}

}
